// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

.intel_syntax noprefix
#include <AsmOffsets.inc>         // generated by the build from AsmOffsets.cpp
#include <unixasmmacros.inc>

//
// RhpPInvoke
//
// IN:  RDI: address of pinvoke frame
//
// This helper assumes that its callsite is as good to start the stackwalk as the actual PInvoke callsite.
// The codegenerator must treat the callsite of this helper as GC triggering and generate the GC info for it.
// Also, the codegenerator must ensure that there are no live GC references in callee saved registers.
//
NESTED_ENTRY RhpPInvoke, _TEXT, NoHandler
        push_nonvol_reg rbx
        mov         rbx, rdi

        // RAX = GetThread()
        INLINE_GETTHREAD

        mov         r11, [rsp + 0x8]            // r11 <- return address
        mov         qword ptr [rbx + OFFSETOF__PInvokeTransitionFrame__m_pThread], rax
        mov         qword ptr [rbx + OFFSETOF__PInvokeTransitionFrame__m_FramePointer], rbp
        mov         qword ptr [rbx + OFFSETOF__PInvokeTransitionFrame__m_RIP], r11

        lea         r11, [rsp + 0x10]           // r11 <- caller SP
        mov         dword ptr [rbx + OFFSETOF__PInvokeTransitionFrame__m_Flags], PTFF_SAVE_RSP
        mov         qword ptr [rbx + OFFSETOF__PInvokeTransitionFrame__m_PreservedRegs], r11

        mov         qword ptr [rax + OFFSETOF__Thread__m_pTransitionFrame], rbx
        pop_nonvol_reg rbx
        ret
NESTED_END RhpPInvoke, _TEXT


//
// RhpPInvokeReturn
//
// IN:  RDI: address of pinvoke frame
//
LEAF_ENTRY RhpPInvokeReturn, _TEXT
        mov         rsi, [rdi + OFFSETOF__PInvokeTransitionFrame__m_pThread]
        mov         qword ptr [rsi + OFFSETOF__Thread__m_pTransitionFrame], 0
        cmp         dword ptr [C_VAR(RhpTrapThreads)], TrapThreadsFlags_None
        jne         0f                  // forward branch - predicted not taken
        ret
0:
        // passing transition frame pointer in rdi
        jmp         C_FUNC(RhpWaitForGC2)
LEAF_END RhpPInvokeReturn, _TEXT
